package com.xxx.mch.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.xxx.mch.dao.QualityScoreMapper;
import com.xxx.mch.dao.QualityScoreTemplateMapper;
import com.xxx.mch.domain.dto.QualityScoreTemplateDto;
import com.xxx.mch.domain.po.QualityScore;
import com.xxx.mch.domain.po.QualityScoreTemplate;
import com.xxx.mch.domain.po.TotalScore;
import com.xxx.mch.domain.request.QualityScoreTemplateRequest;
import com.xxx.mch.domain.request.QueryScoreRequest;
import com.xxx.mch.domain.request.RuleSearchRequest;
import com.xxx.mch.exception.BusinessException;
import com.xxx.mch.service.QualityScoreService;
import javax.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.weekend.Weekend;
import tk.mybatis.mapper.weekend.WeekendCriteria;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author FengHaixin
 * @description 一句话描述该文件的用途
 * @date 2020/2/26
 */
@Service
public class QualityScoreServiceImpl implements QualityScoreService
{
    @Autowired
    private ApplicationContext applicationContext;

    @Resource
    private QualityScoreMapper qualityScoreMapper;

    @Resource
    private QualityScoreTemplateMapper qualityScoreTemplateMapper;


    @Override
    public PageInfo<QualityScore> queryScoreRecord(QueryScoreRequest queryScoreRequest)
    {
        Page<QualityScore> page = PageHelper.startPage(queryScoreRequest.getPage(), queryScoreRequest.getPageSize());
        return page.doSelectPageInfo(() -> {
            Weekend<QualityScore> weekend = new Weekend<>(QualityScore.class);
            WeekendCriteria<QualityScore, Object> criteria = weekend.weekendCriteria();
            criteria.andEqualTo(QualityScore::getUid, queryScoreRequest.getUid());
            criteria.andCondition(
                    "DATE_FORMAT(STR_TO_DATE(publish_time,\"%Y-%m-%d %H:%i:%s\"), '%Y-%m')= '" + queryScoreRequest.getDate() + "'");

            if (!CollectionUtils.isEmpty(queryScoreRequest.getFilters()))
            {
                criteria.andIn(QualityScore::getEvaluateId, queryScoreRequest.getFilters());
            }
            qualityScoreMapper.selectByExample(weekend);
        });
    }


    @Override
    @Transactional (rollbackFor = Exception.class)
    public void saveScore(QualityScore qualityScore)
    {
        QualityScoreTemplate template = qualityScoreTemplateMapper.selectByPrimaryKey(qualityScore.getRuleId());
        if (Objects.isNull(template))
        {
            throw new BusinessException("细则不存在！");
        }
        if (Objects.isNull(template.getScore()))
        {
            throw new BusinessException("模板细则分数不存在！");
        }
        qualityScore.setScore(template.getScore());
        qualityScoreMapper.insertSelective(qualityScore);

        TotalScore totalScore = new TotalScore();
        totalScore.setUid(qualityScore.getUid());
        totalScore.setAllowanceScore(qualityScore.getScore());
        totalScore.setQualityScore(qualityScore.getScore());
        applicationContext.publishEvent(totalScore);
    }


    public List<QualityScore> queryEvaluateFilter(QueryScoreRequest queryScoreRequest)
    {
        return qualityScoreMapper.queryEvaluateFilter(queryScoreRequest);
    }


    public List<QualityScore> queryLevelFilter(QueryScoreRequest queryScoreRequest)
    {
        return qualityScoreMapper.queryLevelFilter(queryScoreRequest);
    }


    @Override
    public List<QualityScoreTemplateDto> getTaskTemplate(Integer parentId, Integer depth)
    {
        List<QualityScoreTemplate> templates = qualityScoreTemplateMapper.selectRoot(parentId);
        List<QualityScoreTemplateDto> taskScoreTemplateDtoList = this.convert(templates);
        this.querySubContext(taskScoreTemplateDtoList, --depth);
        return taskScoreTemplateDtoList;
    }


    @Override
    public void createOrUpdateTemplate(List<QualityScoreTemplateRequest> templateRequestList)
    {
        if (CollectionUtils.isEmpty(templateRequestList))
        {
            return;
        }

        templateRequestList.forEach(this::doCreateOrUpdateTemplate);
    }


    @Override
    public void deleteTemplate(Integer templateId)
    {
        List<QualityScoreTemplate> templateList = qualityScoreTemplateMapper.select(new QualityScoreTemplate().setParentId(templateId));
        if (!CollectionUtils.isEmpty(templateList))
        {
            throw new BusinessException("该菜单下还有子菜单，请先删除子菜单");
        }
        qualityScoreTemplateMapper.deleteByPrimaryKey(templateId);
    }


    @Override
    public List<QualityScoreTemplateDto> ruleSearch(RuleSearchRequest ruleSearchRequest)
    {
        Weekend<QualityScoreTemplate> weekend = new Weekend<>(QualityScoreTemplate.class);
        WeekendCriteria<QualityScoreTemplate, Object> criteria = weekend.weekendCriteria();
        criteria.andEqualTo(QualityScoreTemplate::getParentId, ruleSearchRequest.getParentId());
        criteria.andLike(QualityScoreTemplate::getName, "%" + ruleSearchRequest.getName() + "%");
        return this.convert(qualityScoreTemplateMapper.selectByExample(weekend));
    }


    private void querySubContext(List<QualityScoreTemplateDto> templates, Integer depth)
    {
        //终止条件
        if (CollectionUtils.isEmpty(templates) || depth <= 0)
        {
            return;
        }

        for (QualityScoreTemplateDto taskScoreTemplate : templates)
        {
            Weekend<QualityScoreTemplate> weekend = new Weekend<>(QualityScoreTemplate.class);
            weekend.orderBy("sequence").orderBy("createTime");
            WeekendCriteria<QualityScoreTemplate, Object> criteria = weekend.weekendCriteria();
            criteria.andEqualTo(QualityScoreTemplate::getParentId, taskScoreTemplate.getId());
            List<QualityScoreTemplate> subContextList = qualityScoreTemplateMapper.selectByExample(weekend);
            //设置为下一级
            List<QualityScoreTemplateDto> taskScoreTemplateDtoList = this.convert(subContextList);
            taskScoreTemplate.setChildren(taskScoreTemplateDtoList);
            this.querySubContext(taskScoreTemplateDtoList, --depth);
            ++depth;
        }
    }


    private List<QualityScoreTemplateDto> convert(List<QualityScoreTemplate> templates)
    {
        return templates.stream().map(qualityScoreTemplate -> {
            QualityScoreTemplateDto templateDto = new QualityScoreTemplateDto();
            BeanUtils.copyProperties(qualityScoreTemplate, templateDto);
            return templateDto;
        }).collect(Collectors.toList());
    }


    private void doCreateOrUpdateTemplate(QualityScoreTemplateRequest templateRequest)
    {
        QualityScoreTemplate template = new QualityScoreTemplate();
        BeanUtils.copyProperties(templateRequest, template);

        if (this.isCreate(templateRequest))
        {
            this.doCreate(template);
        }
        else
        {
            this.doUpdate(template);
        }

        List<QualityScoreTemplateRequest> subContext = templateRequest.getChildren();
        if (CollectionUtils.isEmpty(subContext))
        {
            return;
        }
        subContext.forEach(taskScoreTemplate -> {
            taskScoreTemplate.setParentId(template.getId());
            this.doCreateOrUpdateTemplate(taskScoreTemplate);
        });

    }


    private void doUpdate(QualityScoreTemplate template)
    {
        //template.setType();
        qualityScoreTemplateMapper.updateByPrimaryKeySelective(template);

    }


    private void doCreate(QualityScoreTemplate template)
    {
        template.setStatus(true);
        qualityScoreTemplateMapper.insertSelective(template);
    }


    private boolean isCreate(QualityScoreTemplateRequest templateRequest)
    {
        return Objects.isNull(templateRequest.getId());
    }
}
